home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ui / waissearch.c < prev    next >
C/C++ Source or Header  |  1994-10-05  |  23KB  |  740 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    Brewster@think.com
  6. */
  7.  
  8. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  9.  
  10.  
  11. /* This is a simple shell user interface for generating wprot packets.
  12.  * -brewster 7/90
  13.  *
  14.  * $Log: waissearch.c,v $
  15.  * Revision 1.8  1994/10/06  13:28:06  pfeifer
  16.  * Patch from Mariusz Niewczas
  17.  *
  18.  * Revision 1.7  1994/09/27  17:27:30  pfeifer
  19.  * Steve Hsieh: 100000 -> BUFSZ
  20.  *
  21.  * Revision 1.6  1994/09/07  13:31:13  pfeifer
  22.  * ctype is now included from cdialect.h after inclusion of string.h.
  23.  * ds, inclusion
  24.  * of string.h after that caused probems
  25.  *
  26.  * Revision 1.5  1994/08/08  07:33:09  pfeifer
  27.  * Moved wais_log_file_name and waislogfile to cutil.[ch]
  28.  *
  29.  * Revision 1.3  1994/04/06  23:55:24  pfeifer
  30.  * 08, autoconf
  31.  *
  32.  * Revision 1.2  1994/03/11  09:13:19  pfeifer
  33.  * some fixes ?
  34.  *
  35.  * Revision 1.3  93/07/02  19:26:46  warnock
  36.  * fix call to getdomainname from mike@tab00.larc.nasa.gov
  37.  * 
  38.  * Revision 1.2  93/07/01  19:22:15  warnock
  39.  * gethostname -> mygethostname
  40.  * 
  41.  * Revision 1.1  93/06/23  20:02:19  warnock
  42.  * Initial revision
  43.  * 
  44.  * Revision 1.1  1993/02/16  15:09:27  freewais
  45.  * Initial revision
  46.  *
  47.  * Revision 1.34  92/06/03  17:29:49  jonathan
  48.  * Fixed so it exits on NULL input.
  49.  * 
  50.  * Revision 1.33  92/04/29  13:21:12  jonathan
  51.  * Updated for release.
  52.  * 
  53.  * Revision 1.32  92/04/09  14:19:53  morris
  54.  * now, specifying a port on the command line does a remote search on the
  55.  * local machine at the specified port.  the previous behavior was to do a
  56.  * local search, even when you specify a port.
  57.  * 
  58.  * Revision 1.31  92/03/17  14:39:28  jonathan
  59.  * modified to work with new ui scheme.
  60.  * 
  61.  * Revision 1.30  92/03/06  14:50:34  jonathan
  62.  * Correctly handle init_connection <= 0.
  63.  * 
  64.  * Revision 1.29  92/03/06  12:34:57  jonathan
  65.  * Use result of init_connection to set message length.
  66.  * 
  67.  * Revision 1.28  92/02/29  20:04:32  jonathan
  68.  * Fixed spelling of opening.
  69.  * 
  70.  * Revision 1.27  92/02/21  11:47:48  jonathan
  71.  * fixed code to re-init properly (instead of using connect_to_server).
  72.  * 
  73.  * Revision 1.26  92/02/20  16:13:15  jonathan
  74.  * Added -m for max results.
  75.  * 
  76.  * Revision 1.25  92/02/16  12:13:36  jonathan
  77.  * Added domainname to init message.
  78.  * 
  79.  *
  80.  * Important functions:
  81.  *   display_search_response
  82.  *   main
  83.  *
  84.  */
  85.  
  86. /* to do:
  87.  *  fix the number parser in view document number
  88.  *  fix if <cr> put to view document number, same as q
  89.  *  show the index again after viewing a document
  90.  *  do a 'more' type thing on viewing the doc  
  91.  *  do something to allow relevance feedback
  92.  */
  93.  
  94. #ifndef lint
  95. static char *RCSid = "$Header: /usr/local/ls6/src+data/src/freeWAIS-sf/ui/RCS/waissearch.c,v 1.8 1994/10/06 13:28:06 pfeifer Exp $";
  96. #endif
  97.  
  98. #include <ui.h>
  99. #include <sockets.h>
  100. #include <docid.h>
  101. /* Security patch from mike@tab00.larc.nasa.gov */
  102. #include <cdialect.h>
  103. /*#include <sys/types.h>*/
  104.  
  105. #define MAX_MESSAGE_LEN BUFSZ
  106. #define CHARS_PER_PAGE 10000 /* number of chars retrieved in each request */
  107. #define MAX_FILE_NAME_LEN 1000
  108. #define Z39_50_SERVICE "210"
  109.  
  110. #define WAISSEARCH_DATE "Thu Aug 27 1992"
  111.  
  112. /* modified from Jonny G's version in ui/question.c */
  113. void showDiags(d)
  114. diagnosticRecord **d;
  115. {
  116.   long i;
  117.  
  118.   for (i = 0; d[i] != NULL; i++) {
  119.     if (d[i]->ADDINFO != NULL) {
  120.       printf("Code: %s, %s\n", d[i]->DIAG, d[i] ->ADDINFO);
  121.     }
  122.   }
  123. }
  124.  
  125. /* modified from tracy shen's version in wutil.c
  126.  * displays either a text record of a set of headlines.
  127.  */
  128. void
  129. display_search_response(response)
  130. SearchResponseAPDU *response;
  131.  
  132. {
  133.   WAISSearchResponse  *info;
  134.   long continue_viewing;
  135.   long i, k;
  136.  
  137.   printf("\n Search Response:\n");
  138.  
  139.   printf("  NumberOfRecordsReturned: %d\n", 
  140.      response->NumberOfRecordsReturned); 
  141.   if ( response->DatabaseDiagnosticRecords != 0 ) {
  142.     info = (WAISSearchResponse *)response->DatabaseDiagnosticRecords;
  143.     i =0; 
  144.     continue_viewing = 1; 
  145.  
  146.     if (info->Diagnostics != NULL)
  147.       showDiags(info->Diagnostics);
  148.  
  149.     if ( info->DocHeaders != 0 ) {
  150.       k =0;
  151.       while ( (continue_viewing == 1) && info->DocHeaders[k] != 0 ) {
  152.     i++;
  153.     printf("  %2d: Score: %4ld, lines:%4ld '%s'\n", 
  154.            i, (info->DocHeaders[k]->Score),
  155.            info->DocHeaders[k]->Lines,
  156.            trim_junk(info->DocHeaders[k]->Headline));
  157.     k++;
  158.       }
  159.     }
  160.     if ( info->ShortHeaders != 0 ) {
  161.       k =0;
  162.       while ( (continue_viewing == 1) && info->ShortHeaders[k] != 0 ) {
  163.     i++;
  164.     printf("\n    ShortHeader record %2d, (can't display)", i);
  165.       }
  166.     }
  167.     if ( info->LongHeaders != 0 ) {
  168.       k =0;
  169.       while ( (continue_viewing == 1) && (info->LongHeaders[k] != 0) ) {
  170.     i++;
  171.     printf("\n    Longheader record %2d, (cant display) ", i);
  172.     /* dsply_long_hdr_record( info->LongHeaders[k++]); */
  173.       }
  174.     }
  175.     if ( info->Text != 0 ) {
  176.       k =0;
  177.       while ( (continue_viewing == 1) && (info->Text[k] != 0) ) {
  178.     i++;
  179.     printf("\n    Text record %2d, ", i);
  180.     display_text_record_completely( info->Text[k++], false);
  181.       }
  182.     }
  183.     if ( info->Headlines != 0 ) {
  184.       k =0;
  185.       while ( (continue_viewing ==1) && (info->Headlines[k] != 0) ) {
  186.     i++;
  187.     printf("\n    headline record %2d, (cant display) ", i);
  188.     /* dsply_headline_record( info->Headlines[k++]); */
  189.       }
  190.     }
  191.     if ( info->Codes != 0 ) {
  192.       k =0;
  193.       while ( (continue_viewing ==1) && (info->Codes[k] != 0) ) {
  194.     i++;
  195.     printf("\n    code record %2d, (dont knowhow to display) ", i);
  196.     /* dsply_code_record( info->Codes[k++]); */
  197.       }
  198.     }
  199.   }                /* display user info */
  200. }
  201.  
  202.  
  203.  
  204. #define MAX_KEYWORDS_LENGTH 1000
  205. #define MAX_SERVER_LENGTH 1000
  206. #define MAX_DATABASE_LENGTH 1000
  207. #define MAX_SERVICE_LENGTH 1000
  208.  
  209. void
  210. main(argc, argv)
  211. int argc;
  212. char *argv[];
  213. {
  214.   char userInfo[500];
  215.   char* request_message = NULL; /* arbitrary message limit */
  216.   char* response_message = NULL; /* arbitrary message limit */
  217.   long request_buffer_length;    /* how of the request is left */
  218.   SearchResponseAPDU  *query_response;
  219.   SearchResponseAPDU  *retrieval_response;
  220.   WAISSearchResponse  *query_info, *retrieval_info;
  221.   char keywords[MAX_KEYWORDS_LENGTH + 1];
  222.   char server_name[MAX_SERVER_LENGTH + 1];    
  223.   char service[MAX_SERVICE_LENGTH + 1];
  224.   char database[MAX_DATABASE_LENGTH + 1];
  225.   char *next_argument, *command_name;
  226.   long count, Max_Docs = 40, message_length = MAX_MESSAGE_LEN;
  227.   FILE *connection;
  228.  
  229. #ifdef THINK_C
  230.   argc = ccommand(&argv);
  231. #endif
  232.  
  233.   next_argument = next_arg(&argc, &argv);
  234.   command_name = next_argument;
  235.  
  236.   if(0 == argc){        /* no args */
  237.     printf("Usage: %s\n", command_name);
  238.     printf("       [-h host-machine]    /* defaults to localhost */\n");
  239.     printf("       [-p service-or-port] /* defaults to z39_50 */\n");
  240.     printf("       [-d database]        /* defaults to nil */\n");
  241.     printf("       [-m maximum_results] /* defaults to 40 /*\n");
  242.     printf("       [-v]                 /* print the version */\n");
  243.     printf("       word word...\n");
  244.     exit(0);
  245.   }
  246.   
  247. #ifdef THINK_C
  248.   strncpy(server_name,"wais:System Folder:wais-index:index",MAX_SERVER_LENGTH);
  249. #else
  250.   server_name[0] = '\0';  /* null it out */
  251. #endif    /* THINK_C */
  252.  
  253.   database[0] = '\0';  /* null it out */
  254.   service[0] = '\0';
  255.  
  256.   if(NULL == (next_argument = next_arg(&argc, &argv))){
  257.     printf("No arguments specified\n");
  258.     exit(0);
  259.   }
  260.   while('-' == next_argument[0]){
  261.     /* then we have an argument to process */
  262.     if(0 == strcmp("-debug", next_argument)){
  263.       waislogfile = stderr;
  264.     }
  265.     else if(0 == strcmp("-h", next_argument)){
  266.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  267.     printf("Expected a hostname\n");
  268.     exit(0);
  269.       }
  270.       strncpy(server_name, next_argument, MAX_SERVER_LENGTH);
  271.     }
  272.     else if((0 == strcmp("-s", next_argument)) || /* -s is for backcompatibility */
  273.         (0 == strcmp("-p", next_argument))){
  274.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  275.     printf("Expected a service name or portname\n");
  276.     exit(0);
  277.       }
  278.       strncpy(service, next_argument, MAX_SERVICE_LENGTH);
  279.     }    
  280.     else if(0 == strcmp("-d", next_argument)){
  281.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  282.     printf("Expected a database name\n");
  283.     exit(0);
  284.       }
  285.       strncpy(database, next_argument, MAX_DATABASE_LENGTH);
  286.     }
  287.     else if(0 == strcmp("-m", next_argument)){
  288.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  289.     printf("Expected a number\n");
  290.     exit(0);
  291.       }
  292.       Max_Docs = atoi(next_argument);
  293.     }
  294.     else if(0 == strcmp("-v", next_argument)){
  295.       printf("%s version: %s, %s\n",
  296.          command_name, VERSION, WAISSEARCH_DATE);
  297.     }
  298.     else{
  299.       panic("Don't recognize the %s option", next_argument);
  300.     }
  301.     if(NULL == (next_argument = next_arg(&argc, &argv))){
  302.       printf("No search words specified\n");
  303.       exit(0);
  304.     }
  305.   }
  306.   /* collect up the words for the query */
  307.   strncpy(keywords, next_argument, MAX_KEYWORDS_LENGTH);
  308.   while(NULL != (next_argument = next_arg(&argc, &argv))){
  309.     strncat(keywords, " ", MAX_KEYWORDS_LENGTH);
  310.     strncat(keywords, next_argument, MAX_KEYWORDS_LENGTH);
  311.   }
  312.     
  313.   
  314.   if (server_name[0] == '\0' && service[0] == '\0')
  315.     connection = NULL; /* do local searching */
  316.   else /* remote search, fill in defaults if necessary */
  317.    { if (server_name[0] == '\0')
  318.        mygethostname(server_name,MAX_SERVER_LENGTH); /*default to local machine*/
  319.      if (service[0] == '\0')
  320.        strcpy(service, Z39_50_SERVICE); /* default */
  321.      if ((connection = connect_to_server(server_name,atoi(service))) == NULL) 
  322.       {    fprintf (stderr, "Error opening connection to %s via service %s.\n",
  323.          server_name, service);
  324.     exit(-1);
  325.       }
  326.    }
  327.  
  328.   /* init logging if we want to.  this is just for timing studies */
  329.   read_environment_variables(server_name, service);
  330.  
  331.   request_message = (char*)s_malloc((size_t)message_length * sizeof(char));
  332.   response_message = (char*)s_malloc((size_t)message_length * sizeof(char));
  333.  
  334.   {
  335.     char hostname[80];
  336. /*    char domainname[80]; */
  337.     char *domainname;
  338.     struct hostent *my_host_ent;
  339.  
  340.     mygethostname(hostname, 80);
  341. /* Security patch from mike@tab00.larc.nasa.gov */
  342.     if (((my_host_ent = gethostbyname(hostname)) == NULL) ||
  343.     (domainname = (char *)index(my_host_ent->h_name, '.')) == NULL)
  344.       domainname = "unknown";
  345.     else
  346.       domainname++;
  347. /*    getdomainname(domainname, 80); */
  348.  
  349. #ifdef TELL_USER
  350.     sprintf(userInfo, "waissearch %s, from host: %s.%s, user: %s",
  351.         VERSION, hostname, domainname, getenv("USER"));
  352. #else
  353.     sprintf(userInfo, "waissearch %s, from host: %s.%s", 
  354.         VERSION, hostname, domainname);
  355. #endif
  356.  
  357.     if((message_length = 
  358.     init_connection(request_message, response_message,
  359.             message_length,
  360.             connection,
  361.             userInfo)) <= 0) {
  362.       fprintf (stderr, "Error opening connection to %s via service %s.\n",
  363.            server_name, service);
  364.       exit(-1);
  365.     }
  366.   }
  367.  
  368.   while(1){        /* continue to search until the user gets tired */
  369.     request_buffer_length = message_length; /* how of the request is left */
  370.     if(NULL ==
  371.     generate_search_apdu(request_message + HEADER_LENGTH, 
  372.                  &request_buffer_length, 
  373.                  keywords, database, NULL, Max_Docs)) {
  374.       printf("Error creating search APDU: request too large");
  375.       break;
  376.     }
  377.  
  378.     if(0 ==
  379.        interpret_message(request_message, 
  380.              message_length - request_buffer_length, 
  381.              response_message,
  382.              message_length,
  383.              connection,
  384.              false    /* true verbose */
  385.              )) { /* perhaps the server shut down on us, let's see: */
  386.       if ( connection != NULL) {
  387.     fclose(connection);
  388.     if ((message_length = 
  389.           init_connection(request_message, response_message,
  390.                   message_length,
  391.                   connection,
  392.                   userInfo)) <= 0)
  393.       {
  394.         fprintf (stderr, "Error opening connection to %s via service %s.\n",
  395.              server_name, service);
  396.         exit(-1);
  397.       }
  398.     if(0 ==
  399.        interpret_message(request_message, 
  400.                  message_length - request_buffer_length, 
  401.                  response_message,
  402.                  message_length,
  403.                  connection,
  404.                  false /* true verbose */
  405.                  ))
  406.       panic("really couldn't deliver message");
  407.     }
  408.       else
  409.     panic("returned message too large");
  410.     }
  411.  
  412.     readSearchResponseAPDU(&query_response, response_message + HEADER_LENGTH);
  413.     display_search_response(query_response);
  414.     query_info = (WAISSearchResponse *)query_response->DatabaseDiagnosticRecords;
  415.  
  416.     if ( query_response->DatabaseDiagnosticRecords != 0 &&
  417.     query_info->DocHeaders !=0) {
  418.       long document_number = -1;
  419.       any* lastDocID = NULL;
  420.  
  421.       while(1){            /* keep viewing until user wants out */
  422.     while(1){        /* keep asking until we have an answer */
  423.       char document_string[1000]; /* to hold the users response */
  424.       long count;
  425.  
  426.       if(document_number>0 && 
  427.          document_number<query_response->NumberOfRecordsReturned)
  428.         lastDocID = query_info->DocHeaders[document_number-1]->DocumentID;
  429.  
  430.       printf("\nView document number [type 0 or q to quit]: ");
  431.       fflush(stdout);
  432. /* tung */
  433. /*      if(NULL == fgets(document_string, 1000, stdin)) {
  434.         close_connection(connection);
  435.         exit(-1);
  436.       } */
  437.           fgets(document_string, 1000, stdin);
  438.           if(document_string[0] == '\0') {
  439.             close_connection(connection);
  440.         exit(-1);
  441.       }
  442. /* tung */
  443.       /* trim \n from string */
  444.       if(strlen(document_string) > 0)
  445.         document_string[strlen(document_string) -1] = '\0';
  446.  
  447.       if(document_string[0] == 'q'){
  448.         document_number = 0; /* signal to quit */
  449.         break;
  450.       }
  451.       if(document_string[0] == 'n'){
  452.         if(NULL == lastDocID){
  453.           printf("A document first must be selected\n");
  454.         }
  455.         else{
  456.           document_number = -3; /* signal to get next document */
  457.           break;
  458.         }
  459.       }
  460.       if(document_string[0] == 'p'){
  461.         if(NULL == lastDocID){
  462.           printf("A document first must be selected\n");
  463.         }
  464.         else{
  465.           document_number = -2; /* signal to get previous document */
  466.           break;
  467.         }
  468.       }
  469.       /* check for a number */
  470.       for(count = 0; count < strlen(document_string); count++){
  471.         if(!isdigit(document_string[count])){
  472.           document_number = -1; /* ask again */
  473.           break;        /* break out of for loop */
  474.         }
  475.       }
  476.       if (count == strlen(document_string)){
  477.         /* it is a legal number */
  478.         document_number = atol(document_string);
  479.       }
  480.       if(document_number >= 0 &&
  481.          document_number <= query_response->NumberOfRecordsReturned){
  482.         break;        /* correct entry */
  483.       }
  484.       printf("\nEntry must be a number between 0 and %ld [type 0 or q to quit] you entered \"%s\"\n", query_response->NumberOfRecordsReturned, document_string);
  485.       
  486.     }
  487.     if(document_number == 0){
  488.       break;        /* leave the viewing loop */
  489.     }
  490.     if(document_number < -1) { /* handle next and previous */
  491.       char *type;
  492.       DocObj *Doc[2];
  493.               
  494.       if(document_number == -3)
  495.         type = "WAIS_NEXT";
  496.       else if(document_number == -2)
  497.         type = "WAIS_PREV";
  498.       request_buffer_length = message_length; /* how of the request is left */
  499.       Doc[0] =
  500.         makeDocObjUsingWholeDocument(lastDocID, type);
  501.       Doc[1] = NULL;
  502.  
  503.       if(0 ==
  504.          generate_search_apdu(request_message + HEADER_LENGTH, 
  505.                   &request_buffer_length, 
  506.                   "foo", database, Doc, 1)) {
  507.         panic("request too long");
  508.       }
  509.       if(0 ==
  510.          interpret_message(request_message, 
  511.                    message_length - request_buffer_length, 
  512.                    response_message,
  513.                    message_length,
  514.                    connection,
  515.                    false /* true verbose */    
  516.                    )) { /* perhaps the server shut down on us, let's see: */
  517.         if ( connection != NULL) {
  518.           fclose(connection);
  519.           if (0 == init_connection(request_message, response_message,
  520.                        message_length,
  521.                        connection,
  522.                        userInfo))
  523.         {
  524.           fprintf (stderr, "Error opening connection to %s via service %s.\n",
  525.                server_name, service);
  526.           exit(-1);
  527.         }
  528.           if(0 ==
  529.          interpret_message(request_message, 
  530.                    message_length - request_buffer_length, 
  531.                    response_message,
  532.                    message_length,
  533.                    connection,
  534.                    false /* true verbose */
  535.                    ))
  536.         panic("really couldn't deliver message");
  537.         }
  538.         else
  539.           panic("returned message too large");
  540.       }
  541.  
  542.         readSearchResponseAPDU(&retrieval_response, 
  543.                    response_message + HEADER_LENGTH);
  544.  
  545.         retrieval_info = (WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords;
  546.  
  547.         if ( retrieval_info != NULL &&
  548.         retrieval_info->DocHeaders != NULL) {
  549.           char *type;
  550.           long size;
  551.  
  552.         lastDocID = duplicateAny(retrieval_info->DocHeaders[0]->DocumentID);
  553.         if(retrieval_info->DocHeaders[0]->Types == NULL)
  554.           type = s_strdup("TEXT");
  555.         else
  556.           type = s_strdup(retrieval_info->DocHeaders[0]->Types[0]);
  557.         printf("Headline: %s\n", 
  558.            retrieval_info->DocHeaders[0]->Headline);
  559.         size = retrieval_info->DocHeaders[0]->DocumentLength;
  560.         for(count = 0; 
  561.         count * CHARS_PER_PAGE < size;
  562.         count++){
  563.           request_buffer_length = message_length; /* how of the request is left */
  564.           if(0 ==
  565.          generate_retrieval_apdu(request_message + HEADER_LENGTH,
  566.                      &request_buffer_length, 
  567.                      lastDocID,
  568.                      CT_byte,
  569.                      count * CHARS_PER_PAGE,
  570.                      MINIMUM((count + 1) * CHARS_PER_PAGE, size),
  571.                      type,
  572.                      database
  573.                      )) {
  574.         printf("Error generating retrieval APDU: request too long");
  575.         break;
  576.           }
  577.           if(0 ==
  578.          interpret_message(request_message, 
  579.                    message_length - request_buffer_length, 
  580.                    response_message,
  581.                    message_length,
  582.                    connection,
  583.                    false /* true verbose */    
  584.                    )) { /* perhaps the server shut down on us, let's see: */
  585.         if ( connection != NULL) {
  586.           fclose(connection);
  587.           if ((connection=connect_to_server(server_name,atoi(service))) == NULL) 
  588.             {
  589.               fprintf (stderr, "Error opening connection to %s via service %s.\n",
  590.                    server_name, service);
  591.               exit(-1);
  592.             }
  593.           if(0 ==
  594.              interpret_message(request_message, 
  595.                        message_length - request_buffer_length, 
  596.                        response_message,
  597.                        message_length,
  598.                        connection,
  599.                        false /* true verbose */
  600.                        )) {
  601.             printf("really couldn't deliver message");
  602.             break;
  603.           }
  604.         }
  605.         else {
  606.           printf("returned message too large");
  607.           break;
  608.         }
  609.           }
  610.  
  611.           readSearchResponseAPDU(&retrieval_response, 
  612.                      response_message + HEADER_LENGTH);
  613.  
  614.           /* display_search_response(retrieval_response); the general thing */
  615.           if(NULL == ((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text){
  616.         display_search_response(retrieval_response);
  617.         printf("No text was returned");
  618.         break;
  619.           }
  620.           display_text_record_completely
  621.         (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false);
  622.         }
  623.       }
  624.       freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords); 
  625.       freeSearchResponseAPDU( retrieval_response);
  626.     }
  627.     else {
  628.       printf("Headline: %s\n", 
  629.          query_info->DocHeaders[document_number - 1]->Headline);
  630.       /* we must retrieve the document in parts since it might be very long*/
  631.       for(count = 0; 
  632.           (query_info->DocHeaders[document_number - 1]->DocumentLength == 0) ||
  633.           (count * CHARS_PER_PAGE <
  634.           query_info->DocHeaders[document_number - 1]->DocumentLength);
  635.           count++){
  636.         char *type;
  637.         if(query_info->DocHeaders[document_number - 1]->Types == NULL)
  638.           type = s_strdup("TEXT");
  639.         else
  640.           type = s_strdup(query_info->DocHeaders[document_number - 1]->Types[0]);
  641.         request_buffer_length = message_length; /* how of the request is left */
  642.         if(0 ==
  643.            generate_retrieval_apdu(request_message + HEADER_LENGTH,
  644.                        &request_buffer_length, 
  645.                        query_info->DocHeaders[document_number - 1]->DocumentID, 
  646.                        CT_byte,
  647.                        count * CHARS_PER_PAGE,
  648.                        (query_info->DocHeaders[document_number - 1]->DocumentLength ? 
  649.                     MINIMUM((count + 1) * CHARS_PER_PAGE,
  650.                         query_info->DocHeaders[document_number - 1]->DocumentLength) :
  651.                     (count + 1) * CHARS_PER_PAGE),
  652.                        type,
  653.                        database
  654.                        )) {
  655.           printf("Error generating retrieval APDU: request too long");
  656.           break;
  657.         }
  658.          
  659.         if(0 ==
  660.            interpret_message(request_message, 
  661.                  message_length - request_buffer_length, 
  662.                  response_message,
  663.                  message_length,
  664.                  connection,
  665.                  false /* true verbose */    
  666.                  )) { /* perhaps the server shut down on us, let's see: */
  667.           if ( connection != NULL) {
  668.         fclose(connection);
  669.         if ((connection=connect_to_server(server_name,atoi(service))) == NULL) 
  670.           {
  671.             fprintf (stderr, "Error opening connection to %s via service %s.\n",
  672.                  server_name, service);
  673.             exit(-1);
  674.           }
  675.         if(0 ==
  676.            interpret_message(request_message, 
  677.                      message_length - request_buffer_length, 
  678.                      response_message,
  679.                      message_length,
  680.                      connection,
  681.                      false /* true verbose */
  682.                      )) {
  683.           printf("really couldn't deliver message");
  684.           break;
  685.         }
  686.           }
  687.           else {
  688.         printf("Error deliverring message");
  689.         break;
  690.           }
  691.         }
  692.  
  693.         readSearchResponseAPDU(&retrieval_response, 
  694.                    response_message + HEADER_LENGTH);
  695.  
  696.         /* display_search_response(retrieval_response); the general thing */
  697.         if(NULL == ((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text){
  698.           display_search_response(retrieval_response);
  699.           printf("No text was returned");
  700.           break;
  701.         }
  702.         display_text_record_completely
  703.           (((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Text[0], false);
  704.         if(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Diagnostics != NULL) {
  705.           showDiags(((WAISSearchResponse *)retrieval_response->DatabaseDiagnosticRecords)->Diagnostics);
  706.           break;
  707.         }
  708.       }
  709.       freeWAISSearchResponse( retrieval_response->DatabaseDiagnosticRecords); 
  710.       freeSearchResponseAPDU( retrieval_response);
  711.     }
  712.       }
  713.     }
  714.  
  715.     freeWAISSearchResponse(query_response->DatabaseDiagnosticRecords);         
  716.     freeSearchResponseAPDU( query_response);
  717.     printf("Search for new words [type q to quit]: ");
  718.     fflush(stdout);
  719. #if 0
  720.     if(NULL == gets(keywords) ||
  721.        (strlen(keywords) == 1 && keywords[0] == 'q')){
  722.       close_connection(connection);
  723.       break;            /* leave the asking loop */
  724.     }
  725. #endif
  726.     fgets(keywords,MAX_KEYWORDS_LENGTH,stdin);
  727.     if(keywords == NULL ||
  728.        (strlen(keywords) <= 3 && keywords[0] == 'q')){
  729.       close_connection(connection);
  730.       break;            /* leave the asking loop */
  731.     }
  732.     
  733.   }
  734.  
  735.   s_free(request_message);
  736.   s_free(response_message);
  737.  
  738.   exit(0);
  739. }
  740.